package services

type observer interface {
	// sampleDataUpdate 有新的样本点数据时触发，将currentIndex(包含)和sampleIndex(包含)之间的数据推送到客户端（这样可以处理失败重发和乱序的情况）
	sampleDataUpdate(sampleIndex int)
	// reduceIndex 因为dac中的samples数组大小会改变，当samples数组大小减小时，observer中保存的currentIndex也要对应减小
	reduceIndex(indexReduced int)
}

type pushToClientObserver struct {
	dacName      string
	currentIndex int // 下一个需要发送的点的下标（currentIndex尚未发送）
	pushFunc     func(data []sampleData) error
	cleanUpFunc  func()
}

// reduceIndex 因为dac中的samples数组大小会改变，当samples数组大小减小时，observer中保存的currentIndex也要对应减小
func (observer *pushToClientObserver) reduceIndex(indexReduced int) {
	if observer.currentIndex-indexReduced < 0 {
		observer.currentIndex = 0
	} else {
		observer.currentIndex = observer.currentIndex - indexReduced
	}
}

// sampleDataUpdate 有新的样本点数据时触发，将currentIndex(包含)和sampleIndex(包含)之间的数据推送到客户端（这样可以处理失败重发和乱序的情况）
func (observer *pushToClientObserver) sampleDataUpdate(sampleIndex int) {
	if observer.currentIndex > sampleIndex {
		return
	}
	dac := dacDataMap.get(observer.dacName)
	if err := observer.pushFunc(dac.Samples[observer.currentIndex : sampleIndex+1]); err != nil {
		observer.cleanUpFunc()
	} else {
		observer.currentIndex = sampleIndex + 1
	}
}

// pushRecent 尝试将dacName的最近样本点数据推送到客户端，并更新currentIndex
func (observer *pushToClientObserver) pushRecent() {
	// recentLimit 最近样本点数目最大值
	const recentLimit int = 300
	dac := dacDataMap.get(observer.dacName)
	sampleIndex := len(dac.Samples) - 1
	if len(dac.Samples) > recentLimit {
		observer.currentIndex = len(dac.Samples) - recentLimit
	} else {
		observer.currentIndex = 0
	}
	observer.sampleDataUpdate(sampleIndex)
}
